package com.nuonuo.es.service;

import com.nuonuo.es.vo.BuyerBaseInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @author duan
 * @version 1.0
 * @date 2023/7/17 19:27
 */
@Component
public class NewBuyerInfoService {

    private static final String BUYER_BASIC_INFO_INDEX_ALIAS = "buyer_baseinfo";

    private static final String TYPE = "buyer_baseinfo";

    private final TransportClient transportClient;

    public NewBuyerInfoService(TransportClient transportClient) {
        this.transportClient = transportClient;
    }


    public SearchResponse query(String buyerName, String saleTaxNum, int pageStart,
                                int pageSize, boolean totalFlag) {
        BoolQueryBuilder builder = getQueryBuilder(buyerName, saleTaxNum);
        SearchResponse response = transportClient.prepareSearch(getIndex()).setTypes(TYPE)
                .setTrackTotalHits(totalFlag)
                .setQuery(builder).addSort("add_date", SortOrder.DESC).addSort("c_id", SortOrder.DESC)
                .setFrom(pageStart).setSize(pageSize).execute().actionGet();

        return response;
    }

    public boolean exist(String buyerName, String saleTaxNum, Long id) {
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        // 销方税号精确查询
        builder.filter(QueryBuilders.termQuery("c_saletaxnum", saleTaxNum));
        builder.filter(QueryBuilders.termQuery("c_buyername.keyword", buyerName));
        if (id != null) {
            builder.mustNot(QueryBuilders.termQuery("c_id", id));
        }
        SearchResponse response = transportClient.prepareSearch(getIndex()).setTypes(TYPE)
                .setQuery(builder).setSize(0).execute().actionGet();

        return response.getHits().getTotalHits() != 0;
    }


    public SearchResponse findByBuyerNmAndSaleTaxnum(String buyerName, String saleTaxNum) {
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        // 销方税号精确查询
        builder.filter(QueryBuilders.termQuery("c_saletaxnum", saleTaxNum));
        builder.filter(QueryBuilders.termQuery("c_buyername.keyword", buyerName));
        SearchResponse response = transportClient.prepareSearch(getIndex()).setTypes(TYPE)
                .setQuery(builder).execute().actionGet();

        return response;
    }

    private BoolQueryBuilder getQueryBuilder(String buyerName, String saleTaxNum) {
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        // 销方税号精确查询
        builder.filter(QueryBuilders.termQuery("c_saletaxnum", saleTaxNum));
        // 名称、购方税号模糊查询
        if (StringUtils.isNotBlank(buyerName)) {
            String regex = "[0-9a-zA-Z]+";
            if (buyerName.matches(regex)) {
                buyerName = buyerName.toLowerCase(Locale.ROOT);
                builder.should(QueryBuilders.termQuery("c_taxnum", buyerName));
                builder.should(QueryBuilders.matchPhraseQuery("c_buyername", buyerName));
                builder.should(QueryBuilders.prefixQuery("c_buyername", buyerName));
                builder.minimumShouldMatch(1);
            } else {
                builder.filter(QueryBuilders.matchPhraseQuery("c_buyername", buyerName));
            }
        }
        return builder;
    }

    public List<Map<String, Object>> fuzzyQueryByName(String buyerName, String saleTaxNum) {
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        // 销方税号精确查询
        builder.filter(QueryBuilders.termQuery("c_saletaxnum", saleTaxNum));
        builder.filter(QueryBuilders.matchPhraseQuery("c_buyername", buyerName));
        SearchResponse response = transportClient.prepareSearch(getIndex()).setTypes(TYPE)
                .setQuery(builder).addSort("add_date", SortOrder.DESC).execute().actionGet();

        List<Map<String, Object>> maps = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            maps.add(hit.getSourceAsMap());
        }
        return maps;
    }

    private String getIndex() {
        return BUYER_BASIC_INFO_INDEX_ALIAS;
    }
}
